package com.service.login.aop;

import com.service.config.utils.StringUtils;
import com.service.login.annotation.DataSource;
import com.service.login.datasource.DynamicDataSource;
import com.service.login.datasource.DynamicDataSourceContextHolder;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @author
 * @version 1.0
 * @date 2021/4/28 15:02
 */
@Aspect
@Component
@Order(-1) // 保证该AOP在@Transactional之前执行
public class DynamicDataSourceAspect {

    protected Logger logger = LoggerFactory.getLogger(getClass());


    @Pointcut("execution(* com.service.login.service..*(..))")
    public void dsPointCut()  {
    }

    //调用方法前结束后,根据注解@DS设置数据源
    @Before("dsPointCut()")
    private void before(JoinPoint point) {
        Object target = point.getTarget();
        String method = point.getSignature().getName();
        Class<?> classz = target.getClass();// 获取目标类
        Class<?>[] parameterTypes = ((MethodSignature) point.getSignature())
                .getMethod().getParameterTypes();
        try {
            Method m = classz.getMethod(method, parameterTypes);
            if (m != null && m.isAnnotationPresent(DataSource.class)) {
                DataSource data = m.getAnnotation(DataSource.class);
                logger.info("method :{},datasource:{}", m.getName(), data.value());
                DynamicDataSourceContextHolder.set(data.value().getValue());// 数据源放到当前线程中
            }
        } catch (Exception e) {
            logger.error("get datasource error ", e);
            //默认选择master
            DynamicDataSourceContextHolder.set("master");// 数据源放到当前线程中
        }
    }

    //调用方法结束后,清空数据源
    @AfterReturning("dsPointCut()")
    public void after(JoinPoint point) {
        DynamicDataSourceContextHolder.clear();
    }

}
